package com.cdn.nodes.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.cdn.common.core.exception.ServiceException;
import com.cdn.common.core.utils.DateUtils;
import com.cdn.common.security.utils.SecurityUtils;
import com.cdn.nodes.domain.EdgeNodesSshPort;
import com.cdn.nodes.domain.dto.EdgeNodeCheckSshDTO;
import com.cdn.nodes.domain.dto.EdgeNodeSshDTO;
import com.cdn.nodes.mapper.EdgeNodesSshPortMapper;
import com.cdn.nodes.mapper.EdgeSshNodeMapper;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cdn.nodes.mapper.EdgeNodeSshMapper;
import com.cdn.nodes.domain.EdgeNodeSsh;
import com.cdn.nodes.service.IEdgeNodeSshService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 节点SSH，用于管理边缘节点的SSH密钥和访问权限Service业务层处理
 * 
 * @author Cinzia
 * @date 2024-12-17
 */
@Service
public class EdgeNodeSshServiceImpl implements IEdgeNodeSshService 
{
    @Resource
    private EdgeNodeSshMapper edgeNodeSshMapper;
    @Resource
    private EdgeSshNodeMapper edgeSshNodeMapper;
    @Resource
    private EdgeNodesSshPortMapper edgeNodesSshPortMapper;

    /**
     * 查询节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * 
     * @param id 节点SSH，用于管理边缘节点的SSH密钥和访问权限主键
     * @return 节点SSH，用于管理边缘节点的SSH密钥和访问权限
     */
    @Override
    public EdgeNodeSsh selectEdgeNodeSshById(Long id)
    {
        return edgeNodeSshMapper.selectEdgeNodeSshById(id);
    }

    /**
     * 查询节点SSH，用于管理边缘节点的SSH密钥和访问权限列表
     * 
     * @param edgeNodeSsh 节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * @return 节点SSH，用于管理边缘节点的SSH密钥和访问权限
     */
    @Override
    public List<EdgeNodeSsh> selectEdgeNodeSshList(EdgeNodeSsh edgeNodeSsh)
    {
        return edgeNodeSshMapper.selectEdgeNodeSshList(edgeNodeSsh);
    }

    /**
     * 新增节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * 
     * @param edgeNodeSsh 节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * @return 结果
     */
    @Override
    public int insertEdgeNodeSsh(EdgeNodeSsh edgeNodeSsh) {
        edgeNodeSsh.setCreateBy(SecurityUtils.getUsername());
        edgeNodeSsh.setCreateTime(DateUtils.getNowDate());
        edgeNodeSsh.setUpdateTime(DateUtils.getNowDate());
        edgeNodeSsh.setUpdateBy(SecurityUtils.getUsername());
        return edgeNodeSshMapper.insertEdgeNodeSsh(edgeNodeSsh);
    }

    /**
     * 修改节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * 
     * @param edgeNodeSsh 节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * @return 结果
     */
    @Override
    public int updateEdgeNodeSsh(EdgeNodeSsh edgeNodeSsh)
    {
        edgeNodeSsh.setUpdateTime(DateUtils.getNowDate());
        edgeNodeSsh.setUpdateBy(SecurityUtils.getUsername());
        return edgeNodeSshMapper.updateEdgeNodeSsh(edgeNodeSsh);
    }

    /**
     * 批量删除节点SSH，用于管理边缘节点的SSH密钥和访问权限
     * 
     * @param ids 需要删除的节点SSH，用于管理边缘节点的SSH密钥和访问权限主键
     * @return 结果
     */
    @Override
    public int deleteEdgeNodeSshByIds(Long[] ids)
    {
        return edgeNodeSshMapper.deleteEdgeNodeSshByIds(ids);
    }

    /**
     * 删除节点SSH，用于管理边缘节点的SSH密钥和访问权限信息
     * 
     * @param id 节点SSH，用于管理边缘节点的SSH密钥和访问权限主键
     * @return 结果
     */
    @Override
    public int deleteEdgeNodeSshById(Long id)
    {
        return edgeNodeSshMapper.deleteEdgeNodeSshById(id);
    }

    /**
     * 测试SSH连接
     * @param edgeNodeCheckSshDTO 包含连接SSH服务器的必要信息
     * @return 返回0表示连接成功，非0表示连接失败
     */
    public int checkSsh(EdgeNodeCheckSshDTO edgeNodeCheckSshDTO) {
        // 创建JSch对象
        JSch jsch = new JSch();
        Session session = null;
        try {
            // 根据提供的EdgeNodeCheckSshVO对象获取连接信息
            String host = edgeNodeCheckSshDTO.getSshHost();
            int port = edgeNodeCheckSshDTO.getSshPort();
            String username = edgeNodeCheckSshDTO.getSshUser();
            String password = edgeNodeCheckSshDTO.getSshKey();

            // 通过JSch创建会话
            session = jsch.getSession(username, host, port);
            session.setPassword(password);

            // 设置会话的配置
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            // 尝试连接
            session.connect();

            // 如果连接成功，返回0
            return 0;
        } catch (JSchException e) {
            e.printStackTrace();
            return -1;
        } finally {
            // 断开会话连接
            if (session != null) {
                session.disconnect();
            }
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public List<EdgeNodeSshDTO> getSshByNodeId(Long[] nodeIds) {
        List<Long> sshIds = edgeSshNodeMapper.getSshByNodeId(nodeIds);
        if (sshIds != null && !sshIds.isEmpty()) {
            List<EdgeNodeSshDTO> sshDTOs = edgeNodeSshMapper.selectEdgeNodeSshByIds(sshIds);
            if (sshDTOs.size() != nodeIds.length) {
                throw new ServiceException("SSH认证信息与节点ID数量不匹配");
            }
            for (int i = 0; i < sshDTOs.size(); i++) {
                sshDTOs.get(i).setNodeId(nodeIds[i]);
            }
            return sshDTOs;
        } else {
            throw new ServiceException("没有对应的SSH认证信息...");
        }
    }

    @Override
    public Long getPortByNodeId(Long nodeId) {
        return edgeNodesSshPortMapper.selectPortByNodeId(nodeId);
    }
}
